package ca.etsmtl.log430.lab3;

import java.util.*;

public class RegisterStudentIntelliSection extends Communication implements
		Runnable {
	boolean Stop = false;

	public RegisterStudentIntelliSection(Integer RegistrationNumber,
			String ComponentName) {
		super(RegistrationNumber, ComponentName);

	} // Constructor

	@Override
	public void update(Observable thing, Object notificationNumber) {
		Menus menu = new Menus();
		// Displays display = new Displays();
		Student myStudent = new Student();
		Course myCourse = new Course();

		// The update() method is an abstract method that is called whenever the
		// notifyObservers() method is called by the Observable class
		// First we check to see if the NotificationNumber is equal to this
		// thread's RegistrationNumber or SYSTEM_SHUT_DOWN. If they are, then we
		// execute - otherwise, we stay idle.

		if (registrationNumber.compareTo((Integer) notificationNumber) == 0) {
			addToReceiverList("ListStudentsComponent");
			addToReceiverList("ListCoursesComponent");

			// Display the students and prompt the user to pick a student

			signalReceivers("ListStudentsComponent");

			myStudent = menu.pickStudent(CommonData.theListOfStudents
					.getListOfStudents());

			if (myStudent != null) {
				// Display the courses that are available and ask the user to
				// pick a
				// course to register for

				signalReceivers("ListCoursesComponent");

				myCourse = menu
						.pickCourseWithoutSection(CommonData.theListOfCourses
								.getListOfCourses());

				if (myCourse != null) {
					// If the selected course and student exist, then complete
					// the
					// registration process.

					CourseList compulsoryCourses = CommonData.theListOfCourses
							.getListOfCourses();
					Course CourseObject = null;
					boolean inscriptionExists = false;

					compulsoryCourses.goToFrontOfList();
					while ((CourseObject = compulsoryCourses.getNextCourse()) != null) {
						if (CourseObject.getCourseID().equals(
								myCourse.getCourseID()))//
							if (courseValidation(myStudent, CourseObject)) {
								myCourse.register(myStudent);
								myStudent.register(CourseObject);
								inscriptionExists = true;
								break;
							}
					} // while

					if (!inscriptionExists) {
						System.out
								.println("\n\n *** Course can't be registered ***");
					} else {
						System.out
								.println("\n\n *** The student has been registered in the course  ***");
						System.out.println(CourseObject.getCourseName() + " "
								+ CourseObject.getCourseID() + " "
								+ CourseObject.getSection() + " "
								+ CourseObject.getDays() + " "
								+ CourseObject.getStartTime() + ":"
								+ CourseObject.getStopTime() + " "
								+ CourseObject.getInstructor());
					}

				} else {

					System.out.println("\n\n *** Course not found ***");

				} // if

			} else {

				System.out.println("\n\n *** Student not found ***");

			} // if

		} // if

		if (SYSTEM_SHUT_DOWN_ID.compareTo((Integer) notificationNumber) == 0) {
			Stop = true;

		} // if

		removeFromReceiverList("ListCoursesComponent");
		removeFromReceiverList("ListStudentsComponent");

	} // update

	// ITSUR
	private boolean courseValidation(Student student, Course course) {
		if (student.getCoursesRegistered().findCourse(course)) {
			System.out.println("\n *** This student has already taken  \""
					+ course.getCourseID() + ":" + course.getCourseName()
					+ "\" course  ***");
			return false;
		}

		student.getCoursesRegistered().goToFrontOfList();
		Course courseRegistered;
		while ((courseRegistered = student.getCoursesRegistered()
				.getNextCourse()) != null) {

			boolean sameDay = false;

			boolean[] courseDays = { course.getDays().contains("L"),
					course.getDays().contains("MA"),
					course.getDays().contains("ME"),
					course.getDays().contains("J"),
					course.getDays().contains("V") };

			boolean[] courseRegisteredDays = {
					courseRegistered.getDays().contains("L"),
					courseRegistered.getDays().contains("MA"),
					courseRegistered.getDays().contains("ME"),
					courseRegistered.getDays().contains("J"),
					courseRegistered.getDays().contains("V") };

			for (int i = 0; i < courseRegisteredDays.length; i++) {
				if (courseRegisteredDays[i] && courseDays[i]) {
					sameDay = true;
				}
			}

			// System.out.println("SameDay");

			if (sameDay) { // Si las materias se imparte el mismo dia revisar
				// los horarios.
				int courseStartTime = Integer.parseInt(course.getStartTime());
				int courseStopTime = Integer.parseInt(course.getStopTime());
				int crStartTime = Integer.parseInt(courseRegistered
						.getStartTime());
				int crStopTime = Integer.parseInt(courseRegistered
						.getStopTime());

				// Si hay cruces de horarios imprimir lo siguiente.
				if ((courseStartTime >= crStartTime)
						&& (courseStartTime < crStopTime)
						|| (courseStopTime > crStartTime)
						&& (courseStopTime < crStopTime)
						|| (crStartTime >= courseStartTime)
						&& (crStartTime < courseStopTime)
						|| (crStopTime > courseStartTime)
						&& (crStopTime < courseStopTime)) {
					System.out
							.println("\n *** Course Schedule Conflicts. This student is already registered in:");
					System.out.println(courseRegistered.getCourseName() + " "
							+ courseRegistered.getCourseID() + " "
							+ courseRegistered.getSection() + " "
							+ courseRegistered.getDays() + " "
							+ courseRegistered.getStartTime() + ":"
							+ courseRegistered.getStopTime() + " "
							+ courseRegistered.getInstructor());
					System.out.println("  can't be registered to:");
					System.out.println(course.getCourseName() + " "
							+ course.getCourseID() + " " + course.getSection()
							+ " " + course.getDays() + " "
							+ course.getStartTime() + ":"
							+ course.getStopTime() + " "
							+ course.getInstructor());
					System.out.println(" ***");
					return false;
				}
			}
		}

		return true;
	}

	public void run() {
		System.out
				.println("\nRegisterStudentIntelliSection Component Started...");

		try {
			while (!Stop) {

				Thread.sleep(1000);

			} // while

			System.out
					.println("\nRegisterStudentIntelliSection Component Shutdown...");

		} catch (Exception e) {

			System.out
					.println("Exception occured in RegisterStudentIntelliSection.run(): "
							+ e);

		} // try-catch

	} // run
} // RegisterStudent